package cn.itcast.bos.web.action.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cn.itcast.bos.domain.base.Area;
import cn.itcast.bos.service.base.IAreaService;
import cn.itcast.bos.utils.base.PinYin4jUtils;

@ParentPackage("json-default")
@Namespace("/")
@Controller
@Actions
@Scope("prototype")
public class AreaAction extends ActionSupport implements ModelDriven<Area> {
    // 模型驱动
    private Area area = new Area();

    @Override
    public Area getModel() {
        // TODO Auto-generated method stub
        return area;
    }

    // 注入service
    @Autowired
    private IAreaService areaService;
    // 接受上传的文件
    private File file;
    private String fileFileName;
    private String fileContentType;

    public void setFile(File file) {
        this.file = file;
    }

    public void setFileFileName(String fileFileName) {
        this.fileFileName = fileFileName;
    }

    public void setFileContentType(String fileContentType) {
        this.fileContentType = fileContentType;
    }

    // 批量导入区域信息
    @Action(value = "area_batchImport", results = {
            @Result(name = "success", type = "redirect", location = "./pages/base/courier.html") })
    public String batchImportArea() throws IOException {

        // 解析xls文件 HSSF
        // 判断是xls还是xlsx
        Sheet sheet = null;
        if (fileFileName.endsWith(".xls")) {
            // 1.加载Excel文件
            HSSFWorkbook hssfWorkbook = new HSSFWorkbook(new FileInputStream(file));
            // 2.得到sheet
            sheet = hssfWorkbook.getSheetAt(0);
        }
        if (fileFileName.endsWith(".xlsx")) {
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream(file));
            sheet = xssfWorkbook.getSheetAt(0);
        }

        // 3.得到每一行row
        List<Area> areas = new ArrayList<Area>();
        for (Row row : sheet) {
            // d定义集合存放area
            // 第一行数据为表头，跳过
            if (row.getRowNum() == 0) {
                continue;
            }
            // 如果出现空格，跳过
            if (row.getCell(0) == null || StringUtils.isBlank(row.getCell(0).getStringCellValue())) {
                continue;
            }
            Area area = new Area();
            area.setId(row.getCell(0).getStringCellValue());
            area.setProvince(row.getCell(1).getStringCellValue());
            area.setCity(row.getCell(2).getStringCellValue());
            area.setDistrict(row.getCell(3).getStringCellValue());
            area.setPostcode(row.getCell(4).getStringCellValue());
            // 生成城市编码和简码
            String province = area.getProvince();
            String city = area.getCity();
            String district = area.getDistrict();
            // 得到省市区的名字（湖北武汉）
            province = province.substring(0, province.length() - 1);
            city = city.substring(0, city.length() - 1);
            district = district.substring(0, district.length() - 1);
            // 得到简码
            String[] headByString = PinYin4jUtils.getHeadByString(province + city + district);
            StringBuffer sb = new StringBuffer();
            for (String string : headByString) {
                sb.append(string);
            }
            area.setShortcode(sb.toString());
            // 添加城市编码
            String citycode = PinYin4jUtils.hanziToPinyin(city);
            area.setCitycode(citycode);
            areas.add(area);
        }
        areaService.batchImportArea(areas);
        return SUCCESS;
    }

    // 分页查询区域信息
    // 属性驱动
    private int rows;
    private int page;

    public void setRows(int rows) {
        this.rows = rows;
    }

    public void setPage(int page) {
        this.page = page;
    }

    @Action(value = "area_pageQuery", results = { @Result(name = "success", type = "json") })
    public String pageQueryArea() {
        Pageable pageable = new PageRequest(page - 1, rows);
        Specification<Area> specification = new Specification<Area>() {
            @Override
            public Predicate toPredicate(Root<Area> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<Predicate>();
                // 按照省查询
                System.out.println(area.getDifferentProvinces() + "======================================");
                if (StringUtils.isNotBlank(area.getDifferentProvinces())) {
                    Predicate p1 = cb.equal(root.get("province").as(String.class), area.getDifferentProvinces());
                    list.add(p1);
                }
                // 按照市查询
                if (StringUtils.isNotBlank(area.getCity())) {
                    Predicate p2 = cb.like(root.get("city").as(String.class), "%" + area.getCity() + "%");
                    list.add(p2);
                }
                // 按照区域查询--模糊查询
                if (StringUtils.isNotBlank(area.getDistrict())) {
                    Predicate p3 = cb.like(root.get("district").as(String.class), "%" + area.getDistrict() + "%");
                    list.add(p3);
                }

                return cb.and(list.toArray(new Predicate[0]));
            }
        };
        Page<Area> areas = areaService.pageQueryArea(specification, pageable);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("total", areas.getTotalElements());
        map.put("rows", areas.getContent());
        ActionContext.getContext().getValueStack().push(map);
        return SUCCESS;
    }

    // 查询全部
    @Action(value = "area_findAll", results = { @Result(name = "success", type = "json") })
    public String findAllArea() {
        // 得到查询到的所有的Area
        List<Area> list = areaService.findAllArea();
        Set<String> differentProvinces = new HashSet<String>();
        // 去重area.getProvince()
        for (Area area : list) {
            differentProvinces.add(area.getProvince());
        }
        List<Area> areas = new ArrayList<Area>();
        for (String province : differentProvinces) {
            Area area = new Area();
            area.setDifferentProvinces(province);
            areas.add(area);
        }

        ActionContext.getContext().getValueStack().push(areas);
        return SUCCESS;
    }

}
